package com.ryder.petmatediarybackend.module.pet.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ryder.petmatediarybackend.common.exception.BusinessException;
import com.ryder.petmatediarybackend.module.pet.dto.CreatePetDTO;
import com.ryder.petmatediarybackend.module.pet.entity.PetProfile;
import com.ryder.petmatediarybackend.module.pet.entity.PetTag;
import com.ryder.petmatediarybackend.module.pet.entity.SysPetTagLibrary;
import com.ryder.petmatediarybackend.module.pet.mapper.PetProfileMapper;
import com.ryder.petmatediarybackend.module.pet.service.PetProfileService;
import com.ryder.petmatediarybackend.module.pet.service.PetTagService;
import com.ryder.petmatediarybackend.module.pet.service.SysPetTagLibraryService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 描述: 宠物档案表(PetProfile)表服务实现类
 * 
 * @author Ryder
 * @version 1.0
 * @since 1.0 // 版本号，指明从哪个版本开始
 * 更新日期: 2025-10-30 15:39:46
 */
@Slf4j
@Service("petProfileService")
@RequiredArgsConstructor
public class PetProfileServiceImpl extends ServiceImpl<PetProfileMapper, PetProfile> implements PetProfileService {

    private final PetTagService petTagService;
    private final SysPetTagLibraryService tagLibraryService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public PetProfile createPet(Long userId, CreatePetDTO dto) {
        log.info("[创建宠物档案] userId={}, petName={}", userId, dto.getPetName());

        // 1. 创建宠物档案
        PetProfile petProfile = new PetProfile();
        BeanUtil.copyProperties(dto, petProfile);
        petProfile.setUserId(userId);
        
        // 生成宠物ID卡号
        String idCardNumber = generateIdCardNumber();
        petProfile.setIdCardPhoto(idCardNumber);
        log.info("[生成宠物ID卡号] idCardNumber={}", idCardNumber);

        // 保存宠物档案
        boolean saved = this.save(petProfile);
        if (!saved) {
            throw new BusinessException("创建宠物档案失败");
        }

        // 2. 处理标签
        if (dto.getTags() != null && !dto.getTags().isEmpty()) {
            savePetTags(petProfile.getId(), dto.getTags());
        }

        log.info("[创建宠物档案成功] petId={}", petProfile.getId());
        return petProfile;
    }

    @Override
    public List<PetProfile> getPetListByUserId(Long userId) {
        LambdaQueryWrapper<PetProfile> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PetProfile::getUserId, userId)
                .orderByDesc(PetProfile::getCreateTime);
        return this.list(wrapper);
    }

    @Override
    public PetProfile getPetDetail(Long userId, Long petId) {
        PetProfile petProfile = this.getById(petId);
        if (petProfile == null) {
            throw new BusinessException("宠物档案不存在");
        }
        if (!petProfile.getUserId().equals(userId)) {
            throw new BusinessException("无权访问该宠物档案");
        }
        return petProfile;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updatePet(Long userId, Long petId, CreatePetDTO dto) {
        log.info("[更新宠物档案] userId={}, petId={}", userId, petId);

        // 1. 验证权限
        PetProfile petProfile = getPetDetail(userId, petId);

        // 2. 更新宠物信息
        BeanUtil.copyProperties(dto, petProfile);
        boolean updated = this.updateById(petProfile);
        if (!updated) {
            throw new BusinessException("更新宠物档案失败");
        }

        // 3. 更新标签
        if (dto.getTags() != null) {
            // 删除旧标签
            petTagService.remove(new LambdaQueryWrapper<PetTag>()
                    .eq(PetTag::getPetId, petId));
            // 保存新标签
            if (!dto.getTags().isEmpty()) {
                savePetTags(petId, dto.getTags());
            }
        }

        log.info("[更新宠物档案成功] petId={}", petId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deletePet(Long userId, Long petId) {
        log.info("[删除宠物档案] userId={}, petId={}", userId, petId);

        // 验证权限
        PetProfile petProfile = getPetDetail(userId, petId);

        // 逻辑删除
        boolean deleted = this.removeById(petId);
        if (!deleted) {
            throw new BusinessException("删除宠物档案失败");
        }

        log.info("[删除宠物档案成功] petId={}", petId);
    }

    /**
     * 生成宠物ID卡号
     * 格式：PM-年月A序号
     * 例如：PM-2510A001（PM + 年后两位 + 月份 + A + 序号）
     * 序号规则：
     * - 001-999：固定3位，前面补0
     * - 1000+：自动扩展为4位及以上
     *
     * @return 宠物ID卡号
     */
    private String generateIdCardNumber() {
        // 1. 查询数据库中的记录总数
        long count = this.count();
        
        // 2. 序号 = 记录数 + 1
        long sequence = count + 1;
        
        // 3. 获取当前日期
        LocalDate now = LocalDate.now();
        String year = String.format("%02d", now.getYear() % 100); // 年份后两位
        String month = String.format("%02d", now.getMonthValue()); // 月份，补零
        
        // 4. 格式化序号：001-999补零，1000+自动扩展
        String sequenceStr;
        if (sequence <= 999) {
            sequenceStr = String.format("%03d", sequence); // 3位补零
        } else {
            sequenceStr = String.valueOf(sequence); // 超过999直接使用数字
        }
        
        // 5. 拼接ID卡号：PM-年月A序号
        String idCardNumber = String.format("PM-%s%sA%s", year, month, sequenceStr);
        
        log.info("[生成ID卡号] 当前记录数={}, 序号={}, ID卡号={}", count, sequence, idCardNumber);
        
        return idCardNumber;
    }

    /**
     * 保存宠物标签
     *
     * @param petId 宠物ID
     * @param tagNames 标签名称列表
     */
    private void savePetTags(Long petId, List<String> tagNames) {
        log.info("[保存宠物标签] petId={}, 标签名称列表={}", petId, tagNames);
        
        // 1. 验证标签名称列表
        if (tagNames == null || tagNames.isEmpty()) {
            log.info("[保存宠物标签] 标签列表为空，跳过保存");
            return;
        }
        
        // 2. 查询标签库中的标签（只查询启用的标签）
        List<SysPetTagLibrary> tagLibraries = tagLibraryService.list(
                new LambdaQueryWrapper<SysPetTagLibrary>()
                        .in(SysPetTagLibrary::getTagName, tagNames)
                        .eq(SysPetTagLibrary::getStatus, 1) // 只查询启用的标签
        );

        if (tagLibraries.isEmpty()) {
            log.warn("[保存宠物标签] 未找到匹配的启用标签, tagNames={}", tagNames);
            return;
        }

        // 3. 记录找到的标签和未找到的标签
        List<String> foundTagNames = tagLibraries.stream()
                .map(SysPetTagLibrary::getTagName)
                .collect(Collectors.toList());
        List<String> notFoundTags = tagNames.stream()
                .filter(name -> !foundTagNames.contains(name))
                .collect(Collectors.toList());
        
        if (!notFoundTags.isEmpty()) {
            log.warn("[保存宠物标签] 以下标签未在标签库中找到: {}", notFoundTags);
        }

        // 4. 创建宠物标签关联记录
        List<PetTag> petTags = tagLibraries.stream()
                .map(tag -> {
                    PetTag petTag = new PetTag();
                    petTag.setPetId(petId);
                    petTag.setTagLibraryId(tag.getId());
                    log.debug("[创建标签关联] petId={}, tagLibraryId={}, tagName={}", 
                            petId, tag.getId(), tag.getTagName());
                    return petTag;
                })
                .collect(Collectors.toList());

        // 5. 批量保存到pet_tag表
        boolean saved = petTagService.saveBatch(petTags);
        if (!saved) {
            log.error("[保存宠物标签失败] petId={}, 标签数量={}", petId, petTags.size());
            throw new BusinessException("保存宠物标签失败");
        } else {
            log.info("[保存宠物标签成功] petId={}, 成功保存标签数={}, 标签详情={}", 
                    petId, petTags.size(), foundTagNames);
        }
    }
}
